package net.cathackers.devel.scmp.chat.impl.xmpp.iqcomponent;

import java.io.File;
import java.io.FileFilter;

import org.apache.log4j.Logger;

import net.cathackers.devel.scmp.chat.impl.xmpp.iqcomponent.interfaces.IQHandler;
import net.cathackers.devel.scmp.factories.SCMPFactory;

public class IQHandlersLoader {
	private Logger logger_ = SCMPFactory.getLogger(IQHandlersLoader.class);
	private String dirPath = SCMPFactory.getXMPPConfiguration().getIQHandlersPath();
	private FileSystemLoader fsLoader_ = new FileSystemLoader(dirPath);
	public synchronized void LoadIQHandlers(IQComponent iqComponent){
	    logger_.debug("Loading IQ Handlers from " + dirPath);
		File file  = new File(dirPath);
		File[] files = file.listFiles(new JavaClassFilter());
		if (files == null) {
		    // this means that the path is invalid
		    File x = new File(dirPath);
		    logger_.error("Couldn't access the directory " + x.getAbsolutePath());
		    return;
		}
/*		Class<?>[] myklasses = IQHandler.class.getDeclaredClasses();
		logger_.info("Found " + myklasses.length + " class(es) as IQHandlers");
		for (Class<?> klass : myklasses) {
		    try {
			Class<? extends IQHandler> handler = klass.asSubclass(IQHandler.class);
			IQHandler iqHandler = handler.newInstance();
			iqHandler.initialize();
			iqComponent.register(iqHandler);
		    }catch(ClassCastException e) {
			logger_.debug("couldn't load class " + klass.getName() + " as IQHandler");
		    } catch (InstantiationException e) {
			logger_.warn("couldn't instantiate class " + klass.getName() + " as IQHandler");
		    } catch (IllegalAccessException e) {
			logger_.warn("access denied to class " + klass.getName() + " as IQHandler");
		    }
		}*/
		// TODO: do a better implementation
		for ( int i = 0 ; i < files.length ; i++){
			try {
			    	Class<?> x = getClass(files[i].getName());
			    	Class<? extends IQHandler> handler = x.asSubclass(IQHandler.class);
				IQHandler iqHandler = handler.newInstance();
				iqHandler.initialize();
				iqComponent.register(iqHandler);
			} catch(ClassCastException e) {
			    logger_.warn("Didn't initialize " + files[i] + " because it doesnt implement IQHandler");
			} catch (ClassNotFoundException e) {
				logger_.error(e.getMessage(), e);
			} catch (InstantiationException e) {
				logger_.error(e.getMessage(), e);
			} catch (IllegalAccessException e) {
				logger_.error(e.getMessage(), e);
			} catch ( RuntimeException e){
			    	logger_.error(e.getMessage(), e);
			} catch (LinkageError  e) {
			    	logger_.error("Error While loading file " + files[i] + " because:" + e.getMessage(), e);
			} catch(Exception e) {
			    	logger_.error(e.getMessage(), e);
			}
		}
	}
	
	private Class<?> getClass(String name) throws ClassNotFoundException{
	    
		return fsLoader_.loadClass(name);
	}
	
	private class JavaClassFilter implements FileFilter{

		@Override
		public boolean accept(File pathname) {
			if (! pathname.isFile()){
				return false;
			}
			if (!pathname.getName().endsWith(".class")){
				return false;
			}
			return true;
		}
	}
}